// Includes
#include "CPositionalLight.h"

#ifdef _WIN32
#include <windows.h>		// Include windows header on the windows platform
#endif
#include <GL/gl.h>		// OpenGL header

namespace EraAstral
{
	namespace graphics
	{
		// Positional light class constructor
		PositionalLight::PositionalLight(core::SceneManager *sceneManager)
			: ILightSource(sceneManager)
		{
			// Allocate memory for position
			m_position = new Vector3();
			
			// Set light type
			m_type = LST_POSITION;
			
			// Find free OpenGL light index
			for (GLenum glLight = GL_LIGHT0; glLight <= GL_LIGHT6; glLight++)
			{
				// Has the light index been used?
				bool glLightIndexUsed = false;
				
				// Loop through active lights
				for (unsigned int i = 0; i < sceneManager->GetLightCount(); i++)
				{
					// Compare enums
					if (sceneManager->GetLight(i)->GetGLLightEnum() == glLight)
					{
						// Light index already used
						glLightIndexUsed = true;
					}
				}
				
				// Check if the index can be used
				if (!glLightIndexUsed)
				{
					m_glLight = glLight;
					break;
				}
			}
			
			sceneManager->AddLight(this);
		}
		
		// Positional light class destructor
		PositionalLight::~PositionalLight()
		{
			// Free memory taken by position
			delete m_position;
		}
		
		// Commits light changes to OpenGL
		void PositionalLight::Commit()
		{
			// Position values
			GLfloat position[] = { m_position->X, m_position->Y, m_position->Z, 1.0f };
			// Set position
			glLightfv(m_glLight, GL_POSITION, position);
		}
		
		// Applies lighting to the current scene
		void PositionalLight::Apply()
		{
			if (!m_enabled)
			{
				// Clear diffuse component of the OpenGL light
				GLfloat diffuse[] = { 0.0f, 0.0f, 0.0f, 0.0f };
				glLightfv(m_glLight, GL_DIFFUSE, diffuse);
			}
			else
			{
				// Set light diffuse component
				glLightfv(m_glLight, GL_DIFFUSE, m_color->GetData());
				
				// Enable light
				glEnable(m_glLight);
			}
		}
		
		// Gets the position of the light source
		Vector3 *PositionalLight::GetPosition() const
		{
			return m_position;
		}
		
		// Sets the position of the light source
		void PositionalLight::SetPosition(const Vector3& position)
		{
			m_position->Set(position);
		}
	}
}
